package com.yonyou.gmmc.service.SAInterface.util;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * 日期类型与字符串类型相互转换
 */
public class DateUtils {

	/**
	 * Base ISO 8601 Date format yyyyMMdd i.e., 20021225 for the 25th day of
	 * December in the year 2002
	 */
	public static final String ISO_DATE_FORMAT = "yyyyMMdd";

	/**
	 * Expanded ISO 8601 Date format yyyy-MM-dd i.e., 2002-12-25 for the 25th
	 * day of December in the year 2002
	 */
	public static final String ISO_EXPANDED_DATE_FORMAT = "yyyy-MM-dd";

	/**
	 * yyyy-MM-dd HH:mm:ss
	 */
	public static String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

	/**
	 * yyyy-MM-dd HH:mm
	 */
	public static final String DATETIME_PATTERN_02 = "yyyy-MM-dd HH:mm";

	/**
	 * yyyy年MM月dd日
	 */
	public static final String CHINESE_EXPANDED_DATE_FORMAT = "yyyy年MM月dd日";

	/**
	 * Default lenient setting for getDate.
	 */
	private static boolean LENIENT_DATE = false;

	/**
	 * 暂时不用
	 * 
	 * @param JD
	 * @return
	 */
	protected static final float normalizedJulian(float JD) {

		float f = Math.round(JD + 0.5f) - 0.5f;

		return f;
	}

	/**
	 * 浮点值转换成日期格式<br>
	 * 暂时不用 Returns the Date from a julian. The Julian date will be converted to
	 * noon GMT, such that it matches the nearest half-Long (i.e., a julian date
	 * of 1.4 gets changed to 1.5, and 0.9 gets changed to 0.5.)
	 *
	 * @param JD
	 *            the Julian date
	 * @return the Gregorian date
	 */
	public static final Date toDate(float JD) {

		/*
		 * To convert a Julian Day Number to a Gregorian date, assume that it is
		 * for 0 hours, Greenwich time (so that it ends in 0.5). Do the
		 * following calculations, again dropping the fractional part of all
		 * multiplicatons and divisions. Note: This method will not give dates
		 * accurately on the Gregorian Proleptic Calendar, i.e., the calendar
		 * you get by extending the Gregorian calendar backwards to years
		 * earlier than 1582. using the Gregorian leap year rules. In
		 * particular, the method fails if Y<400.
		 */
		float Z = (normalizedJulian(JD)) + 0.5f;
		float W = (int) ((Z - 1867216.25f) / 36524.25f);
		float X = (int) (W / 4f);
		float A = Z + 1 + W - X;
		float B = A + 1524;
		float C = (int) ((B - 122.1) / 365.25);
		float D = (int) (365.25f * C);
		float E = (int) ((B - D) / 30.6001);
		float F = (int) (30.6001f * E);
		int day = (int) (B - D - F);
		int month = (int) (E - 1);

		if (month > 12) {
			month = month - 12;
		}

		int year = (int) (C - 4715); // (if Month is January or February) or
										// C-4716 (otherwise)

		if (month > 2) {
			year--;
		}

		Calendar c = Calendar.getInstance();
		c.set(Calendar.YEAR, year);
		c.set(Calendar.MONTH, month - 1); // damn 0 offsets
		c.set(Calendar.DATE, day);

		return c.getTime();
	}

	/**
	 * Returns the days between two dates. Positive values indicate that the
	 * second date is after the first, and negative values indicate, well, the
	 * opposite. Relying on specific times is problematic.
	 *
	 * @param early
	 *            the "first date"
	 * @param late
	 *            the "second date"
	 * @return the days between the two dates
	 */
	public static final int daysBetween(Date early, Date later) {
		java.util.GregorianCalendar calst = new java.util.GregorianCalendar();
		java.util.GregorianCalendar caled = new java.util.GregorianCalendar();
		calst.setTime(early);
		caled.setTime(later);
		// 设置时间为0时
		calst.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		calst.set(java.util.GregorianCalendar.MINUTE, 0);
		calst.set(java.util.GregorianCalendar.SECOND, 0);
		caled.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		caled.set(java.util.GregorianCalendar.MINUTE, 0);
		caled.set(java.util.GregorianCalendar.SECOND, 0);

		// 得到两个日期相差的天数
		int days = ((int) (caled.getTime().getTime() / 1000) - (int) (calst.getTime().getTime() / 1000)) / 3600 / 24;
		return days;
	}

	/**
	 * Returns the days between two dates. Positive values indicate that the
	 * second date is after the first, and negative values indicate, well, the
	 * opposite.
	 *
	 * @param early
	 * @param late
	 * @return the days between two dates.
	 */
	public static final int daysBetween(Calendar early, Calendar later) {

		return (int) (toJulian(later) - toJulian(early));
	}

	/**
	 * Return a Julian date based on the input parameter. This is based from
	 * calculations found at
	 * <a href="http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html">Julian
	 * Day Calculations (Gregorian Calendar)</a>, provided by Bill Jeffrys.
	 * 
	 * @param c
	 *            a calendar instance
	 * @return the julian day number
	 */
	public static final float toJulian(Calendar c) {

		int Y = c.get(Calendar.YEAR);
		int M = c.get(Calendar.MONTH);
		int D = c.get(Calendar.DATE);
		int A = Y / 100;
		int B = A / 4;
		int C = 2 - A + B;
		float E = (int) (365.25f * (Y + 4716));
		float F = (int) (30.6001f * (M + 1));
		float JD = C + D + E + F - 1524.5f;

		return JD;
	}

	/**
	 * 暂时不用 Return a Julian date based on the input parameter. This is based
	 * from calculations found at
	 * <a href="http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html">Julian
	 * Day Calculations (Gregorian Calendar)</a>, provided by Bill Jeffrys.
	 * 
	 * @param date
	 * @return the julian day number
	 */
	public static final float toJulian(Date date) {

		Calendar c = Calendar.getInstance();
		c.setTime(date);

		return toJulian(c);
	}

	/**
	 * 日期增加
	 * 
	 * @param isoString
	 *            日期字符串
	 * @param fmt
	 *            格式
	 * @param field
	 *            年/月/日 Calendar.YEAR/Calendar.MONTH/Calendar.DATE
	 * @param amount
	 *            增加数量
	 * @return
	 * @throws ParseException
	 */
	public static final String dateIncrease(String isoString, String fmt, int field, int amount) {

		try {
			Calendar cal = GregorianCalendar.getInstance();
			cal.setTime(stringToDate(isoString, fmt, true));
			cal.add(field, amount);

			return dateToString(cal.getTime(), fmt);

		} catch (Exception ex) {
			return null;
		}
	}

	/**
	 * Time Field Rolling function. Rolls (up/down) a single unit of time on the
	 * given time field.
	 *
	 * @param isoString
	 * @param field
	 *            the time field.
	 * @param up
	 *            Indicates if rolling up or rolling down the field value.
	 * @param expanded
	 *            use formating char's
	 * @exception ParseException
	 *                if an unknown field value is given.
	 */
	public static final String roll(String isoString, String fmt, int field, boolean up) throws ParseException {

		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(stringToDate(isoString, fmt));
		cal.roll(field, up);

		return dateToString(cal.getTime(), fmt);
	}

	/**
	 * Time Field Rolling function. Rolls (up/down) a single unit of time on the
	 * given time field.
	 *
	 * @param isoString
	 * @param field
	 *            the time field.
	 * @param up
	 *            Indicates if rolling up or rolling down the field value.
	 * @exception ParseException
	 *                if an unknown field value is given.
	 */
	public static final String roll(String isoString, int field, boolean up) throws ParseException {

		return roll(isoString, DATETIME_PATTERN, field, up);
	}

	/**
	 * 字符串转换为日期java.util.Date
	 * 
	 * @param dateText
	 *            字符串
	 * @param format
	 *            日期格式
	 * @param lenient
	 *            日期越界标志
	 * @return
	 */
	public static Date stringToDate(String dateText, String format, boolean lenient) {

		if (dateText == null) {

			return null;
		}

		DateFormat df = null;

		try {

			if (format == null) {
				df = new SimpleDateFormat();
			} else {
				df = new SimpleDateFormat(format);
			}

			// setLenient avoids allowing dates like 9/32/2001
			// which would otherwise parse to 10/2/2001
			df.setLenient(false);

			return df.parse(dateText);
		} catch (ParseException e) {

			return null;
		}
	}

	/**
	 * 字符串转换为日期java.util.Date
	 * 
	 * @param dateText
	 *            字符串
	 * @param format
	 *            日期格式
	 * @return
	 */
	public static Date stringToDate(String dateString, String format) {

		return stringToDate(dateString, format, LENIENT_DATE);
	}

	/**
	 * 字符串转换为日期java.util.Date
	 * 
	 * @param dateText
	 *            字符串
	 */
	public static Date stringToDate(String dateString) {

		return stringToDate(dateString, ISO_EXPANDED_DATE_FORMAT, LENIENT_DATE);
	}

	public static Date stringToDate1(String dateString) {

		return stringToDate(dateString, DATETIME_PATTERN, LENIENT_DATE);
	}

	/**
	 * 根据时间变量返回时间字符串
	 * 
	 * @return 返回时间字符串
	 * @param pattern
	 *            时间字符串样式
	 * @param date
	 *            时间变量
	 */
	public static String dateToString(Date date, String pattern) {

		if (date == null) {

			return null;
		}

		try {

			SimpleDateFormat sfDate = new SimpleDateFormat(pattern);
			sfDate.setLenient(false);

			return sfDate.format(date);
		} catch (Exception e) {

			return null;
		}
	}

	/**
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 * @deprecated
	 */
	public static String dateToStringEnd(Date date, String pattern) {
		return DateUtils.dateToString(date, DateUtils.ISO_EXPANDED_DATE_FORMAT) + " 23:59:59.000";
	}

	/**
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 * @deprecated
	 */
	public static String dateToStringBegin(Date date, String pattern) {
		return DateUtils.dateToString(date, DateUtils.ISO_EXPANDED_DATE_FORMAT) + " 00:00:00.000";
	}

	/**
	 * 根据时间变量返回时间字符串 yyyy-MM-dd
	 * 
	 * @param date
	 * @return
	 */
	public static String dateToString(Date date) {
		return dateToString(date, ISO_EXPANDED_DATE_FORMAT);
	}

	/**
	 * 返回当前时间
	 * 
	 * @return 返回当前时间
	 */
	public static Date getCurrentDateTime() {
		java.util.Calendar calNow = java.util.Calendar.getInstance();
		java.util.Date dtNow = calNow.getTime();

		return dtNow;
	}

	/**
	 * 返回当前日期字符串
	 * 
	 * @param pattern
	 *            日期字符串样式
	 * @return
	 */
	public static String getCurrentDateString(String pattern) {
		return dateToString(getCurrentDateTime(), pattern);
	}

	/**
	 * 返回当前日期字符串 yyyy-MM-dd
	 * 
	 * @return
	 */
	public static String getCurrentDateString() {
		return dateToString(getCurrentDateTime(), ISO_EXPANDED_DATE_FORMAT);
	}

	/**
	 * 返回当前日期+时间字符串 yyyy-MM-dd hh:mm:ss
	 * 
	 * @param date
	 * @return
	 */
	public static String dateToStringWithTime(Date date) {

		return dateToString(date, DATETIME_PATTERN);
	}

	/**
	 * 日期增加-按日增加
	 * 
	 * @param date
	 * @param days
	 * @return java.util.Date
	 */
	public static Date dateIncreaseByDay(Date date, int days) {

		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DATE, days);

		return cal.getTime();
	}

	/**
	 * 日期增加-按月增加
	 * 
	 * @param date
	 * @param days
	 * @return java.util.Date
	 */
	public static Date dateIncreaseByMonth(Date date, int mnt) {

		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, mnt);

		return cal.getTime();
	}

	/**
	 * 日期增加-按年增加
	 * 
	 * @param date
	 * @param mnt
	 * @return java.util.Date
	 */
	public static Date dateIncreaseByYear(Date date, int mnt) {

		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.YEAR, mnt);

		return cal.getTime();
	}

	/**
	 * 日期增加
	 * 
	 * @param date
	 *            日期字符串 yyyy-MM-dd
	 * @param days
	 * @return 日期字符串 yyyy-MM-dd
	 */
	public static String dateIncreaseByDay(String date, int days) {
		return dateIncreaseByDay(date, ISO_DATE_FORMAT, days);
	}

	/**
	 * 日期增加
	 * 
	 * @param date
	 *            日期字符串
	 * @param fmt
	 *            日期格式
	 * @param days
	 * @return
	 */
	public static String dateIncreaseByDay(String date, String fmt, int days) {
		return dateIncrease(date, fmt, Calendar.DATE, days);
	}

	/**
	 * 取得当前日期所在月的最后一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayInMonth(String yearM) {
		String yymmdd = yearM + "01";
		Date date = DateUtils.stringToDate(yymmdd, ISO_DATE_FORMAT);
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, 1);
		cal.add(Calendar.DATE, -1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 23);
		cal.set(java.util.GregorianCalendar.MINUTE, 59);
		cal.set(java.util.GregorianCalendar.SECOND, 59);
		cal.set(GregorianCalendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 取得当前日期所在月的最后一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayInMonth(Date date) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(stringToDate(dateToString(date, "yyyy-MM") + "-01"));
		cal.add(Calendar.MONTH, 1);
		cal.add(Calendar.DATE, -1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 23);
		cal.set(java.util.GregorianCalendar.MINUTE, 59);
		cal.set(java.util.GregorianCalendar.SECOND, 59);
		cal.set(GregorianCalendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 取得当前日期在一个月的第几天
	 * 
	 * @param date
	 * @return
	 */
	public static int getDaysInMonth(Date date) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);

		return cal.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 取得当前日期在月的最后一天。即总天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getAllDaysInMonth(Date date) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);

		return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 取得当前日期所在月的第一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayInMonth(String yearM) {
		String yymmdd = yearM + "01";
		Date date = DateUtils.stringToDate(yymmdd, ISO_DATE_FORMAT);
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		return cal.getTime();
	}

	/**
	 * 取得当前日期所在月的第一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayInMonth(Date date) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		cal.set(java.util.GregorianCalendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 取得当前日期所在月的第一天。
	 * 
	 * @user : WuZheng
	 * @date : 2012-7-18
	 * @param year
	 *            年份
	 * @param month
	 *            月份
	 * @return
	 */
	public static Date getFirstDayInMonth(Integer year, Integer month) {
		Calendar cal = Calendar.getInstance();

		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		return cal.getTime();
	}

	/**
	 * 取得当前日期所在月的第一天
	 * 
	 * @param date
	 * @return
	 */
	public static String getYearMonth(Date date) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);

		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);

		String lastMonth = dateToString(cal.getTime(), ISO_DATE_FORMAT);

		return lastMonth.substring(0, lastMonth.length() - 2);
	}

	/**
	 * 取得当前月的上个月。
	 * 
	 * @return
	 */
	public static String getLastMonthInToday() {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(new Date());
		cal.set(Calendar.DATE, 1);
		cal.add(Calendar.MONTH, -1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);

		String lastMonth = dateToString(cal.getTime(), ISO_DATE_FORMAT);

		return lastMonth.substring(0, lastMonth.length() - 2);
	}

	/**
	 * 取得指定月的上个月。
	 * 
	 * @return
	 */
	public static String getLastMonth(String yearM) {
		String yymmdd = yearM + "01";
		Date date = DateUtils.stringToDate(yymmdd, ISO_DATE_FORMAT);
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		cal.add(Calendar.MONTH, -1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);

		String lastMonth = dateToString(cal.getTime(), ISO_DATE_FORMAT);

		return lastMonth.substring(0, lastMonth.length() - 2);
	}

	/**
	 * 取得指定月的前第十二个月。
	 * 
	 * @return
	 */
	public static String getBeforTwelveMonth(String yearM) {
		String yymmdd = yearM + "01";
		Date date = DateUtils.stringToDate(yymmdd, ISO_DATE_FORMAT);
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		cal.add(Calendar.MONTH, -12);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);

		String lastMonth = dateToString(cal.getTime(), ISO_DATE_FORMAT);

		return lastMonth.substring(0, lastMonth.length() - 2);
	}

	/**
	 * 取得指定月的前第六个月(前半年)。
	 * 
	 * @return
	 */
	public static String getBeforSixMonth(String yearM) {
		String yymmdd = yearM + "01";
		Date date = DateUtils.stringToDate(yymmdd, ISO_DATE_FORMAT);
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DATE, 1);
		cal.add(Calendar.MONTH, -6);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);

		String lastMonth = dateToString(cal.getTime(), ISO_DATE_FORMAT);

		return lastMonth.substring(0, lastMonth.length() - 2);
	}

	/**
	 * return the current month and last month.
	 * 
	 * @return the List is never null.
	 */
	public static List<String> getCurrentAndLastMonth() {
		List<String> yearMs = new ArrayList<String>();
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(new Date());

		String yearM = dateToString(cal.getTime(), ISO_DATE_FORMAT);
		yearM = yearM.substring(0, yearM.length() - 2);
		yearMs.add(yearM);

		cal.set(Calendar.DATE, 1);
		cal.add(Calendar.MONTH, -1);
		yearM = dateToString(cal.getTime(), ISO_DATE_FORMAT);
		yearM = yearM.substring(0, yearM.length() - 2);
		yearMs.add(yearM);

		return yearMs;
	}

	public static String getCurentMonth() {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(new Date());

		String yearM = dateToString(cal.getTime(), ISO_DATE_FORMAT);
		yearM = yearM.substring(0, yearM.length() - 2);

		return yearM;
	}

	/**
	 * 日期字符串格式转换
	 * 
	 * @param src
	 *            日期字符串
	 * @param srcfmt
	 *            源日期格式
	 * @param desfmt
	 *            目标日期格式
	 * @return
	 */
	public static String stringToString(String src, String srcfmt, String desfmt) {
		return dateToString(stringToDate(src, srcfmt), desfmt);
	}

	public static String getCurrentYearWeek() {
		Calendar cal = Calendar.getInstance();
		String rtn = String.format("%4d%2d", cal.get(Calendar.YEAR), cal.get(Calendar.WEEK_OF_YEAR));
		return rtn;
	}

	/**
	 * 两个时间对象的比较
	 * 
	 * @param first
	 *            the "first date"
	 * @param second
	 *            the "second date"
	 * @return 0: first = second <0: first < second >0: first > second
	 */
	public static final long compare(Date first, Date second) {
		if (first == null && second == null) {
			return 0;
		} else if (first == null) {
			return -1;
		} else if (second == null) {
			return 1;
		}

		java.util.GregorianCalendar calst = new java.util.GregorianCalendar();
		java.util.GregorianCalendar caled = new java.util.GregorianCalendar();
		calst.setTime(first);
		caled.setTime(second);
		// 设置时间为0时
		calst.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		calst.set(java.util.GregorianCalendar.MINUTE, 0);
		calst.set(java.util.GregorianCalendar.SECOND, 0);
		caled.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		caled.set(java.util.GregorianCalendar.MINUTE, 0);
		caled.set(java.util.GregorianCalendar.SECOND, 0);

		long start = calst.get(GregorianCalendar.YEAR) * 10000 + calst.get(GregorianCalendar.MONTH) * 100 + calst.get(GregorianCalendar.DAY_OF_MONTH);
		long end = caled.get(GregorianCalendar.YEAR) * 10000 + caled.get(GregorianCalendar.MONTH) * 100 + caled.get(GregorianCalendar.DAY_OF_MONTH);
		return start - end;
	}

	/**
	 * 两个日期的小时差
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static final BigDecimal hoursBetween(Date startDate, Date endDate, int scale) {
		Calendar sc = Calendar.getInstance();
		sc.setTime(startDate);

		Calendar ec = Calendar.getInstance();
		ec.setTime(endDate);

		Long date = ec.getTimeInMillis() - sc.getTimeInMillis();
		BigDecimal result = new BigDecimal(date.toString());
		BigDecimal unit = new BigDecimal("3600000");

		result = result.divide(unit, scale, BigDecimal.ROUND_HALF_EVEN);

		return result;
	}

	/**
	 * 日期是否为空
	 * 
	 * @param date
	 * @return
	 */

	public static final boolean isEmpty(Date date) {
		return (date == null) ? true : date.toString().length() < 1;
	}

	/**
	 * 夏令时判断
	 * 
	 * @param nowDate
	 * @return
	 */
	public static boolean isDaylightSavingTime() {
		Date nowDate = new Date();

		Calendar c = Calendar.getInstance();
		c.set(c.get(Calendar.YEAR), c.get(Calendar.OCTOBER), c.getActualMinimum(Calendar.DAY_OF_MONTH));

		Calendar c2 = Calendar.getInstance();
		c2.set(c2.get(Calendar.YEAR), c2.get(Calendar.MAY), c2.getActualMinimum(Calendar.DAY_OF_MONTH));

		return nowDate.after(c2.getTime()) && nowDate.before(c.getTime());
	}

	/**
	 * 夏令时/非夏令时 中午休息开始时间
	 * 
	 * @param date
	 * @return
	 */
	public static Date getNoonRestStartTime(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);

		if (isDaylightSavingTime()) {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 12, 00, 00);
		} else {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 12, 00, 00);
		}

		return c.getTime();
	}

	/**
	 * 夏令时/非夏令时 下午上班开始时间
	 * 
	 * @param date
	 * @return
	 */
	public static Date getAfterNoonWorkStartTime(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);

		if (isDaylightSavingTime()) {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 14, 00, 00);
		} else {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 13, 30, 00);
		}

		return c.getTime();
	}

	/**
	 * 夏令时/非夏令时 午休小时数
	 * 
	 * @return
	 */
	public static BigDecimal getNoonRestHours() {
		if (isDaylightSavingTime()) {
			return new BigDecimal("2");
		} else {
			return new BigDecimal("1.5");
		}
	}

	/**
	 * 夏令时/非夏令时 下午下班时间
	 * 
	 * @param date
	 * @return
	 */
	public static Date getAfterNoonWorkEndTime(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);

		if (isDaylightSavingTime()) {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 18, 00, 00);
		} else {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 17, 30, 00);
		}

		return c.getTime();
	}

	/**
	 * 夏令时/非夏令时 上午上班开始时间
	 * 
	 * @param date
	 * @return
	 */
	public static Date getNoonWorkStartTime(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);

		if (isDaylightSavingTime()) {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 8, 00, 00);
		} else {
			c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH), 8, 00, 00);
		}

		return c.getTime();
	}

	/**
	 * 时间比较 (yyyy-MM-dd) 等于0:时间相等，小于0:src日期在tgt之前,大于于0:src日期在tgt之后
	 * 
	 * @param srcDate
	 * @param tgtDate
	 * @return
	 */
	public static long cmp(Date srcDate, Date tgtDate) {
		if (srcDate == null && tgtDate == null) {
			return 0;
		} else if (srcDate == null) {
			return -1;
		} else if (tgtDate == null) {
			return 1;
		}

		Calendar lhs = Calendar.getInstance();
		lhs.setTime(srcDate);
		Calendar rhs = Calendar.getInstance();
		rhs.setTime(tgtDate);

		long start = lhs.get(Calendar.YEAR) * 10000 + lhs.get(Calendar.MONTH) * 100 + lhs.get(Calendar.DAY_OF_MONTH);
		long end = rhs.get(Calendar.YEAR) * 10000 + rhs.get(Calendar.MONTH) * 100 + rhs.get(Calendar.DAY_OF_MONTH);
		return start - end;

	}

	/**
	 * 计算计算两个日期之间的年数
	 * 
	 * @param early
	 * @param late
	 * @return
	 */
	public static final int yearBetween(Date early, Date late) {
		if (early == null || late == null) {
			return 0;
		}
		int years = 0;
		// 计算两个日期之间的年数
		Calendar cEarly = Calendar.getInstance();
		cEarly.setTime(early);
		Calendar cLate = Calendar.getInstance();
		cLate.setTime(late);
		years = cLate.get(Calendar.YEAR) - cEarly.get(Calendar.YEAR);
		// 矫正月、日
		cEarly.add(Calendar.YEAR, years);
		if (cEarly.after(cLate)) {
			years--;
		}
		return years;
	}

	/**
	 * 获得入司月份
	 * 
	 * @param enterDate
	 * @return
	 */
	public static Integer calculateMonthEnterInComp(Date enterDate) {
		if (enterDate == null) {
			return 0;
		}
		Calendar calEnterDate = Calendar.getInstance();
		calEnterDate.setTime(enterDate);

		Date currentDate = new Date();
		Calendar paybaseDate = Calendar.getInstance();
		paybaseDate.setTime(currentDate);
		paybaseDate.set(Calendar.MONTH, Calendar.APRIL);

		int years = calEnterDate.get(Calendar.YEAR) - paybaseDate.get(Calendar.YEAR);

		int number = 12 * years + (calEnterDate.get(Calendar.MONTH) - paybaseDate.get(Calendar.MONTH));

		return number;
	}

	/**
	 * 计算中间的月份
	 */
	public static int monthBetween(Date from, Date to) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(to);
		int months = cal.get(Calendar.YEAR) * 12 + cal.get(Calendar.MONTH);

		cal.setTime(from);
		months -= cal.get(Calendar.YEAR) * 12 + cal.get(Calendar.MONTH);

		return months;
	}

	public static boolean isSomeMonth(Date startDate, Date endDate) {
		Calendar cal = Calendar.getInstance();

		cal.setTime(startDate);
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), 1, 0, 0, 0);

		Date sd = cal.getTime();

		cal.setTime(endDate);
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), 1, 0, 0, 0);

		Date ed = cal.getTime();

		return cmp(sd, ed) == 0;

	}

	/**
	 * 返回当前月的前N个月
	 * 
	 * @user : wangyadong
	 * @date : 2012-6-6
	 * @param n
	 * @return List<String>
	 */
	public static List<String> getFirstNMonths(Integer n) {
		List<String> monthList = new ArrayList<String>();
		int i = 0;
		while (i < n) {
			if (i == 0) {
				monthList.add(DateUtils.getLastMonth(DateUtils.dateToString(new Date(), "yyyyMM")));
			} else {
				monthList.add(DateUtils.getLastMonth(monthList.get(i - 1)));
			}
			i++;
		}
		return monthList;
	}

	/**
	 * 返回指定月的前N个月
	 * 
	 * @user : Administrator
	 * @date : 2012-6-7
	 * @param date
	 *            格式为yyyyMM
	 * @param n
	 * @return List<String>
	 */
	public static List<String> getSpecifiedFirstNMonths(String date, Integer n) {
		List<String> monthList = new ArrayList<String>();
		int i = 0;
		while (i < n) {
			if (i == 0) {
				monthList.add(DateUtils.getLastMonth(date));
			} else {
				monthList.add(DateUtils.getLastMonth(monthList.get(i - 1)));
			}
			i++;
		}
		return monthList;
	}

	/**
	 * 比较两个日期大小
	 * 
	 * @param format
	 *            格式
	 * @param date2
	 *            日期2
	 * @param date1
	 *            日期1
	 * @throws Exception
	 * @user : jerry
	 * @date : 2012-6-15
	 */
	public static int compareDate(String date1, String date2, String format) throws Exception {
		try {
			DateFormat df = new SimpleDateFormat(format);
			Date dt1 = df.parse(date1);
			Date dt2 = df.parse(date2);
			if (dt1.getTime() > dt2.getTime()) {
				return 1;
			} else if (dt1.getTime() < dt2.getTime()) {
				return -1;
			} else {
				return 0;
			}
		} catch (Exception exception) {
			exception.printStackTrace();
			throw exception;
		}
	}

	/**
	 * 返回两个Date对象中表示时间较大的Date对象。
	 * 
	 * @user : WuZheng
	 * @date : 2012-7-3
	 * @param dt1
	 *            Date对象
	 * @param dt2
	 *            Date对象
	 * @return 较大的Date对象
	 */
	public static Date max(Date dt1, Date dt2) {
		return compare(dt1, dt2) >= 0 ? dt1 : dt2;
	}

	/**
	 * 得到Date对象所在的季度
	 * 
	 * @user : jerry
	 * @date : 2012-7-30
	 * @param date
	 *            日期
	 * @return
	 */
	public static int getQuarter(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int month = cal.get(Calendar.MONTH);
		return (month + 3) / 3;
	}

	public static String getFirstDayByMonth(String syear, String smonth) {
		Integer year = new Integer(syear);
		Integer month = new Integer(smonth);
		return year + "-" + month + "-1";
	}

	public static String getNextMonthFirstDayByMonth(String syear, String smonth) {
		Integer year = new Integer(syear);
		Integer month = new Integer(smonth);
		Integer nextYear = year;
		Integer nextMonth = month + 1;
		if (month == 12) {
			nextYear = year + 1;
			nextMonth = 1;
		}
		return nextYear + "-" + nextMonth + "-1";
	}

	/**
	 * 取得当前日期所在月的最后一天
	 * 
	 * @param date
	 * @return
	 */
	public static Calendar getLastDayByMonth(String syear, String smonth) {
		String sdate = syear + "-" + smonth + "-1";
		Date date = DateUtils.stringToDate(sdate, ISO_EXPANDED_DATE_FORMAT);
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, 1);
		cal.add(Calendar.DATE, -1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 23);
		cal.set(java.util.GregorianCalendar.MINUTE, 59);
		cal.set(java.util.GregorianCalendar.SECOND, 59);
		cal.set(GregorianCalendar.MILLISECOND, 0);
		return cal;
	}

	/**
	 * 取得两个日期之间的双休天数
	 * 
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	public static long getNonWorkingDays(String beginDate, String endDate) {
		Date st = DateUtils.stringToDate(beginDate, ISO_EXPANDED_DATE_FORMAT);
		Date et = DateUtils.stringToDate(endDate, ISO_EXPANDED_DATE_FORMAT);

		// Calendar cal1 = Calendar.getInstance();
		// cal1.setTime(st);
		// Calendar cal2 = Calendar.getInstance();
		// cal2.setTime(et);

		// long day = 86400000;//一天的millis
		// long mod =(cal2.getTimeInMillis()-cal1.getTimeInMillis())/day;
		// int n = cal1.get(Calendar.DAY_OF_WEEK);//开始日期是周几
		// long cnt = mod/7;//几个整周
		// cnt=cnt*2; //整周的双休天数
		// long yushu = mod%7;

		// Calendar cal1 = Calendar.getInstance();
		// cal1.setTime(st);
		// Calendar cal2 = Calendar.getInstance();
		// cal2.setTime(et);

		Calendar cal = Calendar.getInstance();
		cal.setTime(st);
		long mod = daysBetween(st, et);
		int n = cal.get(Calendar.DAY_OF_WEEK);// 开始日期是周几
		long cnt = mod / 7;// 几个整周
		cnt = cnt * 2; // 整周的双休天数
		long yushu = mod % 7;
		if (n + yushu > 7)
			cnt = cnt + 2;// 过了周六
		if (n + yushu == 7)
			cnt++;// 正好是周六
		return cnt;
	}

	/**
	 * 取得两个日期之间的双休天数
	 * 
	 * @param stdt
	 * @param etdt
	 * @return
	 */
	public static long getNonWorkingDays(Date stdt, Date etdt) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(stdt);
		long mod = daysBetween(stdt, etdt);
		int n = cal.get(Calendar.DAY_OF_WEEK);// 开始日期是周几
		long cnt = mod / 7;// 几个整周
		cnt = cnt * 2; // 整周的双休天数
		long yushu = mod % 7;
		if (n + yushu > 7)
			cnt = cnt + 2;// 过了周六
		if (n + yushu == 7)
			cnt++;// 正好是周六
		return cnt;
	}

	/**
	 * 取得指定月份的所有日期
	 * 
	 * @user : jerry
	 * @date : 2013-7-5
	 * @param year
	 * @param month
	 * @return
	 */
	public static List<Date> getDaysOfMonth(Integer year, Integer month) {
		List<Date> result = new ArrayList<Date>();
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);

		int days = getAllDaysInMonth(cal.getTime());

		for (int i = 1; i <= days; i++) {
			cal.set(Calendar.DAY_OF_MONTH, i);
			result.add(cal.getTime());
		}

		return result;
	}

	public static int getCurrentYear() {
		return Calendar.getInstance().get(Calendar.YEAR);
	}

	/**
	 * 取下个月第一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayNextMonth(Date date) {
		Calendar cal = GregorianCalendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		// 设置时间为0时
		cal.set(java.util.GregorianCalendar.HOUR_OF_DAY, 0);
		cal.set(java.util.GregorianCalendar.MINUTE, 0);
		cal.set(java.util.GregorianCalendar.SECOND, 0);
		cal.set(java.util.GregorianCalendar.MILLISECOND, 0);
		return cal.getTime();
	}

	public static void cmp1(Date begin, Date end) throws Exception {
		// java.util.Date end = dfs.parse("2004-03-26 13:31:40");
		System.out.println(begin.getTime());
		System.out.println(end.getTime());
		long between = (end.getTime() - begin.getTime()) / 1000;// 除以1000是为了转换成秒
		System.out.println(between + "秒");
	}
}
